<?php
/**
 * Created by PhpStorm.
 * User: ari
 * Date: 1/2/2015
 * Time: 8:10 PM
 */
namespace BC\Wallet\Bitcoin;

use BC\SiteIndex;
use BC\User\Session\UserSession;
use CPath\Build\IBuildable;
use CPath\Build\IBuildRequest;
use CPath\Data\Map\ISequenceMap;
use CPath\Data\Map\ISequenceMapper;
use CPath\Render\HTML\Element\HTMLElement;
use CPath\Request\Exceptions\RequestException;
use CPath\Request\Executable\ExecutableRenderer;
use CPath\Request\Executable\IExecutable;
use CPath\Request\IRequest;
use CPath\Request\Session\ISessionRequest;
use CPath\Response\IResponse;
use CPath\Route\IRoutable;
use CPath\Route\RouteBuilder;

class BitcoinUserWallets implements IRoutable, IBuildable, ISequenceMap, IExecutable
{
	const USER_ID = 'user';

	private $mUserFingerprints;


	public function __construct($userFingerprints) {
		$this->mUserFingerprints = $userFingerprints;
	}

	/**
	 * Execute a command and return a response. Does not render
	 * @param IRequest $Request
	 * @throws RequestException
	 * @throws \BC\User\Session\Exceptions\UserSessionNotFound
	 * @throws \CPath\Request\Validation\Exceptions\ValidationException
	 * @return IResponse the execution response
	 */
	function execute(IRequest $Request) {
		if(!$Request instanceof ISessionRequest)
			throw new RequestException("Request does not implement ISessionRequest");

		$Container = new HTMLElement('div', 'form-wallets-container',
			$FieldSetWallets = new HTMLElement('fieldset', 'fieldset-wallets',
				new HTMLElement('legend', 'legend-table', 'Wallets')
			),
			new ExecutableRenderer(
				new BitcoinWalletCreate()
			)
		);

		$Wallets = BitcoinWallet::search($this->mUserFingerprints);
		foreach($Wallets as $Wallet) {
			$FieldSetWallets->addContent(
				new ExecutableRenderer($Wallet)
			);
		}

		return $Container;

	}

	/**
	 * Map sequential data to the map
	 * @param ISequenceMapper $Map
	 */
	function mapSequence(ISequenceMapper $Map) {
		$userFingerprints = $this->mUserFingerprints;
		$Wallets = BitcoinWallet::search($userFingerprints);
		// TODO: map search

		foreach($Wallets as $Wallet) {
			if(true === $Map->mapNext($Wallet))
				break;
		}
	}

	// Static

	/**
	 * Route the request to this class object and return the object
	 * @param IRequest $Request the IRequest inst for this render
	 * @param array|null $Previous all previous response object that were passed from a handler, if any
	 * @param null|mixed $_arg [varargs] passed by route map
	 * @return void|bool|Object returns a response object
	 * If nothing is returned (or bool[true]), it is assumed that rendering has occurred and the request ends
	 * If false is returned, this static handler will be called again if another handler returns an object
	 * If an object is returned, it is passed along to the next handler
	 */
	static function routeRequestStatic(IRequest $Request, Array &$Previous = array(), $_arg = null) {

		$UserSession = UserSession::fromSession($Request);
		$userFingerprints = $UserSession->getUserFingerprints(); // TODO: ask user first
		return new BitcoinUserWallets($userFingerprints);
	}

	/**
	 * Handle this request and render any content
	 * @param IBuildRequest $Request the build request inst for this build session
	 * @return void
	 * @build --disable 0
	 * Note: Use doctag 'build' with '--disable 1' to have this IBuildable class skipped during a build
	 */
	static function handleBuildStatic(IBuildRequest $Request) {
		$Builder = new RouteBuilder($Request, new SiteIndex());
		$Builder->writeRoute('ANY /wallets/', __CLASS__);
		$Builder->writeRoute('ANY /user/:' . self::USER_ID . '/wallets', __CLASS__);
	}
}